#ifndef PAGING_H
#define PAGING_H

#include "common.h"
#include "isr.h"

typedef struct page{
	uint present 	:1;		// Page present in memory
	uint rw			:1;		// ReadOnly if clear, readwrite if set.
	uint user		:1;		// Supervisor level only if clear
	uint accessed	:1;		// Has the page been accessed since last refresh.
	uint dirty		:1;		// Has the page been written to since last refresh.
	uint unused		:1;		// Amalgamation of unused and reserved bits.
	uint frame		:20;	// Frame Address (shifted right 12 bits).
} page_t;

typedef struct page_table{
	page_t pages[1024];
} page_table_t;

typedef struct page_directory{
	// Arrat of pointers to pagetables.
	page_table_t *tables[1024];
	// Array of pointer to the page tables above. but there 
	// ** physical location for loading into the cr3 register.
	uint tablesPhysical[1024];
	
	// The physical address of tablesPhysical.This comes into play when we
	// we get our kernel heap allocated and the directory may be in a different
	// location in virtualmemory.
	uint physicalAddr;
} page_directory_t;

// Sets up the environment, page directories and enables paging.
void init_paging();

// Causes the specified page directory to be loaded into the cr3 register.
void switch_page_directory(page_directory_t *new);

// Retrieves the pointer to the page required.
// If make==1, if the page-table in which this should reside isn't created, 
// create it.
page_t *get_page(uint address, int make, page_directory_t *dir);

// Handler for pageFaults.
void page_fault(registers_t regs);

#endif
